/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package comparison;

import java.util.ArrayList;

import id3.Tree;
import id3.Record;
import id3.Utility;
import java.io.IOException;
import knn.KNN;
import naivebayes.NaiveBayes;
import java.util.Random;


/**
 *
 * @author Lenovo
 */
public class cross_validation {
    public static void random_shuffle(ArrayList<Record> data)
    {
        Record record;
        Random random = new Random();
        int i, j;
        for (i=data.size(); i>0; )
        {
            j = random.nextInt(i--);
            record = data.get(i);
            data.set(i, data.get(j));
            data.set(j, record);
        }
    }

    public static void main (String args[]) throws IOException
    {
        String nama_file = "data/krkopt.data.txt";
        //System.out.println("hasil KNN = "+hitung(1, nama_file, 10));
        //System.out.println("hasil Naive Bayes = "+hitung(2, nama_file, 10));
        //System.out.println("hasil Tree = "+hitung(3, nama_file, 10));
//        ArrayList<Double> A = new ArrayList<Double>();
//        ArrayList<Double> B = new ArrayList<Double>();
//        A.add(82.0);A.add(81.0);A.add(92.0);A.add(92.0);A.add(87.0);A.add(85.0);A.add(84.0);A.add(85.0);A.add(91.0);A.add(81.0);
//        B.add(81.0);B.add(80.0);B.add(97.0);B.add(91.0);B.add(88.0);B.add(89.0);B.add(87.0);B.add(84.0);B.add(93.0);B.add(83.0);
//        double tpair = hitungtPair(A, B);
//        System.out.println(tpair);
    }

    public static double hitung (int kode, String nama_file, int k_fold, ArrayList<Record> data_awal) throws IOException
    {
        ArrayList<Record> records, test_records = new ArrayList<Record>();
        ArrayList<String> hasil;
        int i, j, k, N = data_awal.size(), n_kol = data_awal.get(0).attributes.size();
        double akurasi = 0.0;
        
        j = 0;
        records = data_awal;
        for (i=0; i<k_fold; ++i)
        {
            for (j = test_records.size(); --j>=0; )
            {
                records.add(test_records.get(0));
                test_records.remove(0);
            }
            if (i<k_fold-1)
                k = (i+1)*(N/k_fold);
            else
                k = N;
            for (j=i*(N/k_fold); j<k; ++j)
            {
                test_records.add(records.get(0));
                records.remove(0);
            }
            if (kode == 1)
            {
                KNN knn = new KNN(records, test_records);
                knn.classify();
                hasil = knn.get_hasil_inferensi();
            }
            else if (kode == 2)
            {
                NaiveBayes naivebayes = new NaiveBayes(records, Utility.attributeDetails);
                hasil = naivebayes.inference(test_records);
            }
            else
            {
                Tree tree = new Tree(records, test_records);
                tree.classify();
                hasil = tree.get_hasil_inferensi();
            }
            k = 0;
            for (j=0; j<hasil.size(); ++j)
                if (hasil.get(j).equals(test_records.get(j).attributes.get(n_kol-1).value))
                    ++k;
            if (hasil.size()>0)
                akurasi += 1.0*k/hasil.size()/k_fold;
        }
        return akurasi;
    }

    public static ArrayList<Double> hitung_akurasi (int kode, String nama_file, int k_fold, ArrayList<Record> data_awal) throws IOException
    {
        ArrayList<Record> records, test_records = new ArrayList<Record>();
        ArrayList<String> hasil;
        int i, j, k, N = data_awal.size(), n_kol = data_awal.get(0).attributes.size();
        ArrayList<Double> akurasi = new ArrayList<Double>();

        records = data_awal;
        j = 0;
        for (i=0; i<k_fold; ++i)
        {
            for (j = test_records.size(); --j>=0; )
            {
                records.add(test_records.get(0));
                test_records.remove(0);
            }
            if (i<k_fold-1)
                k = (i+1)*(N/k_fold);
            else
                k = N;
            for (j=i*(N/k_fold); j<k; ++j)
            {
                test_records.add(records.get(0));
                records.remove(0);
            }
            if (kode == 1)
            {
                KNN knn = new KNN(records, test_records);
                knn.classify();
                hasil = knn.get_hasil_inferensi();
            }
            else if (kode == 2)
            {
                NaiveBayes naivebayes = new NaiveBayes(records, Utility.attributeDetails);
                hasil = naivebayes.inference(test_records);
            }
            else
            {
                Tree tree = new Tree(records, test_records);
                tree.classify();
                hasil = tree.get_hasil_inferensi();
            }
            k = 0;
            for (j=0; j<hasil.size(); ++j)
                if (hasil.get(j).equals(test_records.get(j).attributes.get(n_kol-1).value))
                    ++k;
            if (hasil.size()>0)
                akurasi.add(100.0*k/hasil.size());
            else
                akurasi.add(0.0);
        }
        return akurasi;
    }

    public static double hitungtPair(ArrayList<Double> A, ArrayList<Double> B){
        double hasil = 0.0;
        double rata2 = 0.0;
        ArrayList<Double> delta = new ArrayList<Double>();

        //Asumsi size A dan size B selalu sama
        for(int i = 0; i < A.size(); ++i){
            double temp = Math.abs(A.get(i) - B.get(i));
            rata2 += temp;
            delta.add(temp);
        }
        rata2 = rata2/A.size();

        //Hitung standar deviasi
        double deltakuadrat = 0.0;
        for(int i = 0; i < delta.size(); ++i){
            double temp = rata2 - delta.get(i);
            temp = Math.pow(temp, 2);
            deltakuadrat += temp;
        }
        hasil = deltakuadrat/(delta.size()*(delta.size()-1));
        hasil = Math.sqrt(hasil);
        
        return hasil;
    }
}
